package com.songcha.library_common.ui.view.compose

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Rect
import android.graphics.drawable.Drawable
import android.util.TypedValue
import android.widget.ImageView
import androidx.annotation.DrawableRes
import androidx.compose.foundation.Image
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.FilterQuality
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asAndroidBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.imageResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.toSize
import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.content.ContextCompat
import androidx.core.graphics.drawable.toBitmap
import com.songcha.library_common.util.LogUtil
import kotlin.math.roundToInt

@Composable
fun ComposeImage(modifier: Modifier = Modifier,id:Int,contentScale: ContentScale = ContentScale.Crop) {

    /*val context = LocalContext.current
    val imageBitmap = remember(id) {
        ImageBitmap.imageResource(context.resources,id)
    }
    val painter = RecycleBitmapPainter(imageBitmap)//painterResource(id = id)

    DisposableEffect(painter) {
        onDispose {
            val bitmap = painter.getAndroidBitmap()
            bitmap.recycle()
        }
    }*/

    Image(
        modifier = modifier,
        painter = painterResource(id = id),
        contentScale = contentScale,
        contentDescription = null,
    )
}

@Composable
fun painterResourceCompat(@DrawableRes id: Int): Painter {
    val context = LocalContext.current
    val res = context.resources
    val value = remember { TypedValue() }
    res.getValue(id, value, true)
    val path = value.string
    if (path?.endsWith(".xml") == true) {
        return painterResource(id = id)
    }
    val imageBitmap = remember(path, id, context.theme) {
        try {
            ImageBitmap.imageResource(res, id)
        } catch (throwable: Throwable) {
            val drawable: Drawable =
                ContextCompat.getDrawable(context, id) ?: throw IllegalArgumentException("not found drawable, path: $path")
            drawable.toBitmap().asImageBitmap()
        }
    }
    return BitmapPainter(imageBitmap)
}


class RecycleBitmapPainter(
    private val image: ImageBitmap,
    private val srcOffset: IntOffset = IntOffset.Zero,
    private val srcSize: IntSize = IntSize(image.width, image.height)
) : Painter() {

    // Not ideal, however, in order to maintain binary compatibility, leave this as an
    // internal var that we can conditionally configure from a function constructor
    // above.
    // Unfortunately we cannot modify the primary constructor to introduce this optional
    // parameter and we cannot introduce a secondary constructor that includes this parameter
    // due to how Kotlin handles constructors with inline class parameters to maintain Java
    // compatibility. See https://youtrack.jetbrains.com/issue/KT-31980
    internal var filterQuality: FilterQuality = FilterQuality.Low

    private val size: IntSize = validateSize(srcOffset, srcSize)

    private var alpha: Float = 1.0f

    private var colorFilter: ColorFilter? = null

    fun getAndroidBitmap():Bitmap{
        return image.asAndroidBitmap()
    }

    override fun DrawScope.onDraw() {
        drawImage(
            image,
            srcOffset,
            srcSize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            ),
            alpha = alpha,
            colorFilter = colorFilter,
            filterQuality = filterQuality
        )
    }

    /**
     * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height
     */
    override val intrinsicSize: Size get() = size.toSize()

    override fun applyAlpha(alpha: Float): Boolean {
        this.alpha = alpha
        return true
    }

    override fun applyColorFilter(colorFilter: ColorFilter?): Boolean {
        this.colorFilter = colorFilter
        return true
    }

    private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize {
        require(
            srcOffset.x >= 0 &&
                    srcOffset.y >= 0 &&
                    srcSize.width >= 0 &&
                    srcSize.height >= 0 &&
                    srcSize.width <= image.width &&
                    srcSize.height <= image.height
        )
        return srcSize
    }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is RecycleBitmapPainter) return false

        if (image != other.image) return false
        if (srcOffset != other.srcOffset) return false
        if (srcSize != other.srcSize) return false
        if (filterQuality != other.filterQuality) return false
        return true
    }

    override fun hashCode(): Int {
        var result = image.hashCode()
        result = 31 * result + srcOffset.hashCode()
        result = 31 * result + srcSize.hashCode()
        result = 31 * result + filterQuality.hashCode()
        return result
    }

    override fun toString(): String {
        return "BitmapPainter(image=$image, srcOffset=$srcOffset, srcSize=$srcSize, " +
                "filterQuality=$filterQuality)"
    }
}
